package Model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Team class: define data structures of teams
 * @author Jose Filipe M Santos - 7277502
 * @author Matheus Martins Teixeira - 7277482
 */
public class Team implements Serializable {

    /**
     * Nested class StartingPlayer: manage starting players
     */
    private class StartingPlayer implements Serializable{

	public Player player;
	public boolean starting;

	public StartingPlayer(Player p, boolean s) {
	    player = p;
	    starting = s;
	}
    }
    private String name;
    private ArrayList<StartingPlayer> players;
    private int wins;
    private int losts;
    private int draws;

    /**
     * Constructor Team
     * @param pNam  Team name
     */
    public Team(String pNam) {
	name = pNam;
	wins = 0;
	draws = 0;
	losts = 0;
	players = new ArrayList<StartingPlayer>();
    }

    /**
     * Return team name as a string
     * @return  Team name
     */
    public String getName() {
	return name;
    }

    /**
     * Returns the team's number of ties
     *
     * @return Number of team's ties
     */
    public int getDraws() {
	return draws;
    }

    /**
     * Returns the number of games lost
     *
     * @return Number of team's loss
     */
    public int getLosts() {
	return losts;
    }

    /**
     * Returns the number of games won
     *
     * @return Number of team's wins
     */
    public int getWins() {
	return wins;
    }

    /**
     * Returns the team stats
     * @return Wins: X, Draws: X, Loss: 0
     */
    public String getResults() {
	return ("Wins: " + wins + ", Draws: " + draws + ", Loss: " + losts);
    }

    /**
     * Sum 1 to the team's wins record
     */
    public void sumWin() {
	wins++;
    }

    /**
     * Sum 1 to team's loss records
     */
    public void sumLost() {
	losts++;
    }

    /**
     * Sum 1 to team's ties record
     */
    public void sumDraw() {
	draws++;
    }

    /**
     * Insert a new player
     * @param pPlay  Player to insert
     * @param pNum   Player shirt number
     */
    public void insPlayer(Player pPlay, int pNum) {
	StartingPlayer aux = new StartingPlayer(pPlay, false);
	aux.player.setShirt(pNum);
	players.add(aux);
    }

    /**
     * Returns a list of all attack players
     * @return List of team's attack players
     */
    public ArrayList<Player> getAttackPlayers() {
	ArrayList<Player> attackPlayers = new ArrayList<Player>();

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerAt.class).equals(P.player.getClass())) {
		attackPlayers.add(P.player);
	    }
	}

	return attackPlayers;
    }

    public boolean[] getAttackPlayersStatus() {
	boolean attackPlayers[] = null;
	int i = 0;
	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerAt.class).equals(P.player.getClass())) {
		attackPlayers[i] = P.starting;
		i++;
	    }
	}

	return attackPlayers;
    }

    /**
     * Returns a list of starting attack players
     * @return List of team's attack players
     */
    public ArrayList<Player> getStartingAttackPlayers() {
	ArrayList<Player> attackPlayers = new ArrayList<Player>();

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerAt.class).equals(P.player.getClass()) && P.starting) {
		attackPlayers.add(P.player);
	    }
	}
	return attackPlayers;
    }

    /**
     * Returns a list of all defense players
     * @return List of team's defense players
     */
    public ArrayList<Player> getDefensePlayers() {
	ArrayList<Player> defensePlayers = new ArrayList<Player>();

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerDef.class).equals(P.player.getClass())) {
		defensePlayers.add(P.player);
	    }
	}
	return defensePlayers;
    }

    /**
     * Returns a list of all starting defense players
     *
     * @return List of team's defense players
     */
    public ArrayList<Player> getStartingDefensePlayers() {
	ArrayList<Player> defensePlayers = new ArrayList<Player>();

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerDef.class).equals(P.player.getClass()) && P.starting) {
		defensePlayers.add(P.player);
	    }
	}
	return defensePlayers;
    }

    /**
     * Returns a list of all goal keepers in one team
     *
     * @return List of team's goal keepers
     */
    public ArrayList<Player> getGkPlayers() {

	ArrayList<Player> GkPlayers = new ArrayList<Player>();

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerGk.class).equals(P.player.getClass())) {
		GkPlayers.add(P.player);
	    }
	}
	return GkPlayers;
    }

    /**
     * Returns a list of starting goal keepers
     *
     * @return List of selected goal keepers
     */
    public ArrayList<Player> getStartingGkPlayers() {

	ArrayList<Player> GkPlayers = new ArrayList<Player>();

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    if ((PlayerGk.class).equals(P.player.getClass()) && P.starting) {
		GkPlayers.add(P.player);
	    }
	}
	return GkPlayers;
    }

    /**
     * Toggle player starting condition
     * @param identifier of player
     */
    public void ChangeStatus(int index) {
	if (players.get(index).starting == true) {
	    players.get(index).starting = false;
	} else {
	    players.get(index).starting = true;
	}
    }

    /**
     * Return if team is ready to play
     * @return return true if team is ready
     */
    public boolean isReady() {
	boolean isready;
	ArrayList<Player> gk;
	ArrayList<Player> fwd;
	ArrayList<Player> def;

	gk = getStartingGkPlayers();
	fwd = getStartingAttackPlayers();
	def = getStartingDefensePlayers();

	Iterator<Player> gkit = gk.iterator();
	Iterator<Player> fwdit = fwd.iterator();
	Iterator<Player> defit = def.iterator();

	int ngk = 0;
	int ndef = 0;
	int nfwd = 0;

	while (gkit.hasNext()) {
	    ngk++;
	    gkit.next();
	}

	while (fwdit.hasNext()) {
	    nfwd++;
	    fwdit.next();
	}

	while (defit.hasNext()) {
	    ndef++;
	    defit.next();
	}

	if ((ngk == 1) && (nfwd >= 1) && (ndef >= 1) && ((ngk + nfwd + ndef) == 5)) {
	    isready = true;
	} else {
	    isready = false;
	}

	return isready;
    }

    public boolean isStarting(int index) {
	return players.get(index).starting;
    }
    
    public boolean[] getStarting(){
	boolean[] stat = new boolean[15];
	int i = 0;
	
	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    stat[i] = P.starting;
	    i++;
	}
	return stat;
    }

    public void print() {

	Iterator<StartingPlayer> aux = players.iterator();
	while (aux.hasNext()) {
	    StartingPlayer P = aux.next();
	    System.out.println(P.player.getName() + ": "+P.starting);
	}
    }
}
